#include "analyzer_common.h"

int get_triangle(int upper, int onlystruct, sparse_matrix_t *src, sparse_matrix_t *dst)
{ // upper==1:upper upper==0:lower
    if(!src->value){
        onlystruct = 1;
    }
    dst->m = src->m;
    dst->n = src->n;
    dst->nnz = 0;
    dst->is_sym = 0;
    dst->name = NULL;
    // dst->rowpointer = calloc(src->m+1, sizeof(sparse_pointer_t));
    dst->rowpointer = malloc(sizeof(sparse_pointer_t) * (src->m+1));
    memset(dst->rowpointer, 0, sizeof(sparse_pointer_t) * (src->m+1));
    for(sparse_index_t row = 0; row < src->m; row++){
        for(sparse_pointer_t idx = src->rowpointer[row]; idx < src->rowpointer[row+1]; idx++){
            sparse_index_t col = src->columnindex[idx];
            if(upper){
                if(row <= col){
                    dst->rowpointer[row+1]++;
                }
            }else{
                if(row >= col){
                    dst->rowpointer[row+1]++;
                }
            }
        }
    }
    for(sparse_pointer_t row = 0; row < dst->m; row++){
        dst->rowpointer[row+1] += dst->rowpointer[row];
    }
    
    dst->nnz = dst->rowpointer[dst->m];
    dst->columnindex = malloc(sizeof(sparse_index_t) * dst->nnz);
    if(!onlystruct){dst->value = malloc(sizeof(sparse_value_t) * dst->nnz);}
    
    sparse_pointer_t* pointer_tmp = malloc(sizeof(sparse_pointer_t) * (dst->m+1));
    memcpy(pointer_tmp, dst->rowpointer, sizeof(sparse_pointer_t) * (dst->m+1));

    for(sparse_index_t row = 0; row < src->m; row++){
        for(sparse_pointer_t idx = src->rowpointer[row]; idx < src->rowpointer[row+1]; idx++){
            sparse_index_t col = src->columnindex[idx];
            if(upper){
                if(row <= col){
                    dst->columnindex[pointer_tmp[row]] = col;
                    if(!onlystruct){dst->value[pointer_tmp[row]] = src->value[idx];}
                    pointer_tmp[row]++;
                }
            }else{
                if(row >= col){
                    dst->columnindex[pointer_tmp[row]] = col;
                    if(!onlystruct){dst->value[pointer_tmp[row]] = src->value[idx];}
                    pointer_tmp[row]++;
                }
            }
        }
    }

    free(pointer_tmp);
}